package thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author xiongf
 * 实现主线程线程循环10次，次线程循环5次，第三线程循环3次，然后再主，以此不停往复
 * 在此使用的Lock和Condition
 * Conditon的功能类似于在传统线程中Object.wait()和Object.notify()功能
 * Lock 替代了 synchronized 方法和语句的使用，Condition 替代了 Object 监视器方法的使用
 *
 */
public class ConditionCommuncation {

	static Business business = new Business();

	public static void main(String[] args) {
		SubTherad subtherad = new SubTherad();
		Thread subThread = new Thread(subtherad);

		MainThread mainthread = new MainThread();
		Thread mainThread = new Thread(mainthread);

		ThridTherad thridthread = new ThridTherad();
		Thread thridThread = new Thread(thridthread);
		subThread.start();
		mainThread.start();
		thridThread.start();

	}

	static class SubTherad implements Runnable {
		@Override
		public void run() {
			while (true) {
				business.subThread();
			}

		}
	}

	static class MainThread implements Runnable {
		@Override
		public void run() {
			while (true) {
				business.mainThread();
			}
		}
	}

	static class ThridTherad implements Runnable {
		@Override
		public void run() {
			while (true) {
				business.ThridThread();
			}
		}
	}

	static class Business {
		private static int execOrder = 1;

		Lock lock = new ReentrantLock();
		Condition mainCondition = lock.newCondition();
		Condition subCondition = lock.newCondition();
		Condition thridCondition = lock.newCondition();

		public void mainThread() {
			lock.lock();
			while (execOrder != 1) {
				try {
					mainCondition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			for (int j = 1; j < 11; j++) {
				System.out.println("mainthread---" + j);
			}
			execOrder = 2;
			subCondition.signal();
			lock.unlock();
		}

		public void subThread() {
			lock.lock();
			while (execOrder != 2) {
				try {
					subCondition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			for (int j = 1; j < 6; j++) {
				System.out.println("subthread---" + j);
			}
			execOrder = 3;
			thridCondition.signal();
			lock.unlock();
		}

		public void ThridThread() {
			lock.lock();
			while (execOrder != 3) {
				try {
					thridCondition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			for (int i = 1; i < 3; i++) {
				System.out.println("ThridThread---" + i);
			}
			execOrder = 1;
			mainCondition.signal();
			lock.unlock();
		}
	}
}
